/*
 * This is a collection of functions and objects for managing the items and categories view 
 * It use a Object Model we will call the the catalog object model. It is like this:
 * class (object)
 *
 * catalog (myCatalog)
 
  catalogNode
  catalogNode.children
  catalogNode.items
  
  
 * catalog
 * catalog::categoriesList
 * catalog::categoriesList::array(category) (categories)
 * catalog::categoriesList::category[x]::itemsList (itemsList)
 * catalog::categoriesList::category[x]::itemsList:array(smallItem) (items)
 
 */
 
 function myNode() {
	this.children=new Array();
	this.parentNode=null;
}

myNode.prototype.moveToChildren=function (keyWord, value) {
	switch (keyWord) {
		case "position":
			for (var i in this.children) {
				if (i==position) {
					return this.children[i];
				}
			}
			return this;
	}
}

function itemsNode() {
	myNode.call(this);

	this.myItemsView=null;
	this.myItemsBlankView=null;
	this.myItemView=null;
	this.items=new Array();
}

itemsNode.prototype=Object.create(myNode.prototype);

itemsNode.prototype.constructor=itemsNode;

// This function load the items in a category from a json formated string with the items
itemsNode.prototype.loadItems=function (itemsString) {

};
 
// Equivalent to the above function but for the itemsList
itemsNode.prototype.loadItemsListView=function (elementId) {
	var myItemsContainerElements=document.getElementById(elementId).getElementsByTagName("*");
	// Now we get the itemsList prompt
	for (var i in myItemsContainerElements) {
		if (typeof myItemsContainerElements[i].getAttribute != 'function') continue;
		if (myItemsContainerElements[i].getAttribute("myProperty")=="itemsList") {
			this.myItemsBlankView=myItemsContainerElements[i].cloneNode(true);
			break
		}
	}

	var myItemListElements=this.myItemsBlankView.getElementsByTagName("*");
	// Now we get a single item's prompt
	for (var i in myItemListElements) {
		if (typeof myItemListElements[i].getAttribute != 'function') continue;
		if (myItemListElements[i].getAttribute("myProperty")=="items") {
			this.myItemView=myItemListElements[i].cloneNode(true);
			break
		}
	}
};

// Equivalent to above function
itemsNode.prototype.refreshItemsListView=function (elementId) {
	// Method mySetView is instantiated for each item to fill the template and assign it to the smallItem myView variable.
	// We send a clone of myItemsList.myItemView to leave the original intact for further use and also we need to duplicate it for each item.
	for (var i in this.items) {
		this.items[i].mySetView(this.myItemView.cloneNode(true));
	}
	this.myLoadItemsView(this.myItemsBlankView.cloneNode(true));

	var myItemsListContainerElement=document.getElementById(elementId);
	while (myItemsListContainerElement.children[0]) myItemsListContainerElement.removeChild(myItemsListContainerElement.children[0]);
	myItemsListContainerElement.appendChild(this.myItemsView);
};

//This function is similar to the function mySetView of the other objects
itemsNode.prototype.myLoadItemsView= function(myItemsView) {
	this.myItemsView=myItemsView;
	myItemsElements=this.myItemsView.getElementsByTagName("*");
	var myItemPointer=null;
	
	for (var i in myItemsElements) {
		if (typeof myItemsElements[i].getAttribute != 'function') continue;
		if (myItemsElements[i].getAttribute("myProperty")=="items") {
			myItemPointer=myItemsElements[i];
			break;
		}
	}
	for (var i=0; i<this.items.length; i++) {
		myItemPointer.parentNode.appendChild(this.items[i].myView);
	}
	// we remove the template
	myItemPointer.parentNode.removeChild(myItemPointer);
};

// Equivalent to above
// Equivalent to orderItem
function catalogNode() {
	itemsNode.call(this);
	this.myCategoriesView=null;
	this.myCategoriesBlankView=null;
	this.myCategoryView=null;
	
	this.myCategory=new category();
	this.myCategory.parentNode=this;
	
	this.myOrderNode=null;
}

 
catalogNode.prototype=Object.create(itemsNode.prototype);

catalogNode.prototype.constructor=catalogNode;

 
// This function sets the categories and subcategories from a object contained that is defined at the string by the standard JSON
// Categories and subcategories are defined normally by steps. That's mean that first we load root categories and then
// subcategories are being loaded at the correspondents categories
catalogNode.prototype.loadCategories=function (caregoriesString) {

};
// This function is to load the categroies List template fro prompting the categories list. 
// It is equivalent to loadViewOrder but for categories
catalogNode.prototype.loadCategoriesListView=function (elementId) {	
	var myCategoriesContainerElements=document.getElementById(elementId).getElementsByTagName("*");
	//We load the categories list view (template). I make a copy to be independient from the original one that is inserted at the document DOM.

	for (var i in myCategoriesContainerElements) {
		// First we check that getAttribute is a function so there will not be a error when try to exect it
		if (typeof myCategoriesContainerElements[i].getAttribute != 'function') continue;
		if (myCategoriesContainerElements[i].getAttribute("myProperty")=="categoriesList") {
			this.myCategoriesBlankView=myCategoriesContainerElements[i].cloneNode(true);
			break;
		}
	}
	
	var myCategoriesListElements=this.myCategoriesBlankView.getElementsByTagName("*");
	
	// Now we get a single category's prompt
	for (var i in myCategoriesListElements) {
		if (typeof myCategoriesListElements[i].getAttribute != 'function') continue;
		// We get the category prompt from the categoriesList prompt (template) and save it at myCatalog.myCategoriesList.myCategoryView
		if (myCategoriesListElements[i].getAttribute("myProperty")=="categories") {
			this.myCategoryView=myCategoriesListElements[i].cloneNode(true);
			break;
		}
	}
};

// Equivalent to refreshOrderView but for the categoriesList
catalogNode.prototype.refreshCategoriesListView=function (elementId) {
	for (var i=0; i<this.children.length; i++) {
		this.children[i].myCategory.mySetView(this.myCategoryView.cloneNode(true));
	}

	// The different between mySetView and myLoad... functions is that mySet just fills the fields with its own porperties but
	// myLoad fills it with its indexed object view
	this.myLoadCategoriesView(this.myCategoriesBlankView.cloneNode(true));
	
	// We insert the view element at the DOM
	var myCategoriesListContainerElement=document.getElementById(elementId);
	while (myCategoriesListContainerElement.children[0]) myCategoriesListContainerElement.removeChild(myCategoriesListContainerElement.children[0]);
	myCategoriesListContainerElement.appendChild(this.myCategoriesView);
};
 
catalogNode.prototype.moveToChildren=function (keyWord, value) {
	switch (keyWord) {
		case "selected":
			for (var i in this.children) {
				if (this.children[i].myCategory.selected) {
					return this.children[i];
				}
			}
			return this;
		case "categoryId":
			for (var i in this.children) {
				if (this.children[i].myCategory.id==value) {
					return this.children[i];
				}
			}
			return this;
	}
}

//This function is similar to the function mySetView of the other objects
catalogNode.prototype.myLoadCategoriesView= function(myCategoriesView) {
		
	this.myCategoriesView=myCategoriesView;
	myCategoriesElements=this.myCategoriesView.getElementsByTagName("*");
	var domTpPointer=null;
		
	for (var i in myCategoriesElements) {
		if (typeof myCategoriesElements[i].getAttribute != 'function') continue;
		if (myCategoriesElements[i].getAttribute("myProperty")=="categories") {
			domTpPointer=myCategoriesElements[i];
			break;
		}
	}

	for (var i=0; i< this.children.length; i++) {
		//var myCategory=categoryPointer.getCategoryByOrder(i+1);
		domTpPointer.parentNode.appendChild(this.children[i].myCategory.myView);
	}

	// we remove the template
	domTpPointer.parentNode.removeChild(domTpPointer);
};

  // myCatalog is the global variable that contain the catalog object model objects. Any time we need to know the catalog
 // state or to modify any data from it we will do it through this variable. We initialize this variable here.

//var myCatalog=new orderCatalog();

function category() {
	this.id=null;
	this.name=null;
	this.myView=null;
	this.parent_id=null;
	this.selected=false;
	this.sort_order=null;
	this.parentNode=null;
	this.myActionButton=null;
}

	category.prototype.setView=setView;
	// This function generates the category view from the template category view
	category.prototype.mySetView = function(myCategoryView) {
		category.prototype.setView.call(this,myCategoryView);
		var myCategoryElements=myCategoryView.getElementsByTagName("*");
		for (var j in myCategoryElements) {
			if (typeof myCategoryElements[j].getAttribute != 'function') continue;
			// It modifies the href of the category name for adding it the category id that it is necessary for the destination href script to identify the category
			// and sets the link action in a smooth different than usual for the activation when click
			if (myCategoryElements[j].getAttribute("myProperty") == "name") {
				myCategoryElements[j].href=myCategoryElements[j].href+this.id;
				myCategoryElements[j].thisCategory=this;
				initLoadingElements(myCategoryElements[j]);
				myCategoryElements[j].onclick=function () {
					this.thisCategory.myActivate();
					return this.request();
				}
				this.myActionButton=myCategoryElements[j];
				break;
			}
		}
		if (!this.myView) {
			this.myView=myCategoryView; 
		}
		else {
			while (this.myView.children[0]) this.myView.removeChild(this.myView.children[0]);
			this.myView.appendChild(myCategoryView);
		}
		if (this.selected) this.mySetSelected();
	};

	category.prototype.mySetSelected= function() {
		var myElements=new Array();
		if (this.myView.getAttribute("myLooking") == "highlight") myElements.push(this.myView);
			var myCategoryElements=this.myView.getElementsByTagName("*");
			for (var j in myCategoryElements) {
				if (typeof myCategoryElements[j].getAttribute != 'function') continue;
				if (myCategoryElements[j].getAttribute("myLooking") == "highlight") {
					myElements.push(myCategoryElements[j]);
				}
			}
			for (var i in myElements) {
				if (myElements[i].className.indexOf(" selected")==-1) myElements[i].className+=" selected";
			}
		this.selected=true;
	};
	
	category.prototype.mySetUnselected=function() {
		var myElements=new Array();
		if (this.myView.getAttribute("myLooking") == "highlight") myElements.push(this.myView);
			var myCategoryElements=this.myView.getElementsByTagName("*");
			for (var j in myCategoryElements) {
				if (typeof myCategoryElements[j].getAttribute != 'function') continue;
				if (myCategoryElements[j].getAttribute("myLooking") == "highlight") {
					myElements.push(myCategoryElements[j]);
				}
			}
			for (var i in myElements) {
				myElements[i].className=myElements[i].className.replace(/ selected/,'');
			}
			
		this.selected=false;
	};

	category.prototype.myActivate=function() {
		for (var i in this.parentNode.parentNode.children) {
			this.parentNode.parentNode.children[i].myCategory.mySetUnselected();
		}
		this.mySetSelected();
	};
	
	category.prototype.setFromArray = setFromArray;



	
function item() {
	this.id=null;
	this.name=null;
	this.price=null;
	this.myView=null;
	this.parentNode=null;
}

item.prototype.mySetView=setView;

item.prototype.setFromArray=setFromArray;


/*
 * It defines the item object.
 */
function catalogItem() {	
	item.call(this);
	this.description=null;
	this.image=null;
	this.sort_order=null;

}

catalogItem.prototype=Object.create(item.prototype);

catalogItem.prototype.constructor=catalogItem;

	// This function generates the item view from the template item view
	catalogItem.prototype.mySetView=function(myItemView) {
		item.prototype.mySetView.call(this,myItemView);
		// it adds some details that are not filled by the normal properties and the add to the cart performance to the button
		myItemElements=myItemView.getElementsByTagName("*");
		for (var j in myItemElements) {
			if (typeof myItemElements[j].getAttribute != 'function') continue;
			// It modifies the href of the item name for adding it the item id that it is necessary for the destination href script to identify the product
			if (myItemElements[j].getAttribute("myProperty") == "itemLink") {
				myItemElements[j].href=myItemElements[j].href+this.id;
				initLoadingElements(myItemElements[j]);
			}
			if (myItemElements[j].getAttribute("myProperty") == "imageSrc") {
				myItemElements[j].src=this.image;
			}
			if (myItemElements[j].getAttribute("myProperty") == "price") {
				myItemElements[j].innerHTML+=" &euro;";
				
			}
		}
		if (!this.myView) {
			this.myView=myItemView; 
		}
		else {
			while (this.myView.children[0]) this.myView.removeChild(this.myView.children[0]);
			this.myView.appendChild(myItemView);
		}
	};
	
 	// An accessory function to fill an object properties with other object properties
	function setFromArray(obj) {
		for(var key in obj) {
			if (this.hasOwnProperty(key)) {
				if (typeof obj[key] == 'object') continue; //We copy just values not objects
				if (typeof obj[key] == 'function') continue; //We copy just values not methods
				this[key] = obj[key];
			}
		}
	}
	
function setView(myView) {
		var hasAttributes=true;	//There could be new nodes so we got to get the elements eachtime
		while(hasAttributes) {
			hasAttributes=false;
			var myItemElements=myView.getElementsByTagName("*");
			// It will search for the elements that correspond with the properties names to fill them
			for (var j in myItemElements) {
				if (typeof myItemElements[j].getAttribute != 'function') continue;
				if (myItemElements[j].getAttribute("myProperty") in this && !myItemElements[j].myFilled) {
					if (typeof this[myItemElements[j].getAttribute("myProperty")] == 'object') continue; //We copy just values not objects
					if (typeof this[myItemElements[j].getAttribute("myProperty")]== 'function') continue; //We copy just values not methods
					myItemElements[j].innerHTML=this[myItemElements[j].getAttribute("myProperty")];
					myItemElements[j].myFilled=true;
					hasAttributes=true;
					break;
				}
			}
		}
		var myItemElements=myView.getElementsByTagName("*");
		for (var j in myItemElements) {
			if (typeof myItemElements[j].getAttribute != 'function') continue;
			if (typeof myItemElements[j].myFilled == 'undefined') continue;
			if (myItemElements[j].getAttribute("myProperty") in this) {
				if (typeof this[myItemElements[j].getAttribute("myProperty")] == 'object') continue; //We copy just values not objects
				if (typeof this[myItemElements[j].getAttribute("myProperty")]== 'function') continue; //We copy just values not methods
				myItemElements[j].myFilled=false;
			}
		}
}